//
// Created by jiangpenghui on 2023/4/12.
//

#ifndef CMAKECXX_COMTAINER_TEMPLATE_H
#define CMAKECXX_COMTAINER_TEMPLATE_H

template<class Seq, class T, class R>
// 模板函数  apply 入参 Seq类型 ，入参 T::f() 函数 返回R类型
void apply(Seq &seq, R(T::*f)() const) {
    typename Seq::iterator it = seq.begin();
    while (it != seq.end()) {
        // 移动指针 *it++ = *(it++)
        // Seq泛元对象循环调用 R T.f() 函数
        (*(it++)->*f)();
    }
}

template<class Seq, class T, class A>
// 模板函数  apply 入参 Seq类型 ，入参 T::f() 函数 返回R类型
void apply(Seq &seq, void(T::*speak)() const) {
    typename Seq::iterator it = seq.begin();
    while (it != seq.end()) {
        // 移动指针 *it++ = *(it++)
        // Seq泛元对象循环调用 R T.f() 函数
        ((*it++)->speak)();
    }
}

// 调用
//  apply(dogs, &Gromit::speak, 1);
template<class Seq, class T, class R, class A>
void apply(Seq &seq, R(T::*f)(A) ,A a) {
    typename Seq::iterator it = seq.begin();
    while (it != seq.end()) {
        (*(it++)->*f)(a);
    }
}

#include <iostream>

using namespace std;

// 正常类
class Gromit {
    int arf;
    int totalBarks;
public:
    Gromit(int aft = 1) : arf(aft + 1), totalBarks(0) {
        cout << "Gromit  create " << endl;
    }

     void   speak(int) {
        for (int i = 0; i < arf; ++i) {
            cout << "arf! ";
            ++totalBarks;
        }
        std::cout << endl;
    }

    char eat(float) const {
        cout << "chomp !" << endl;
        return 'z';
    }

    int sleep(char, double) const {
        cout << "zzz...." << endl;
        return 0;
    }

    void sit() const {
        cout << "sitting..." << std::endl;
    }
};


#endif //CMAKECXX_COMTAINER_TEMPLATE_H
